home *** CD-ROM | disk | FTP | other *** search
Korn shell script | 1997-08-26 | 3.6 KB | 144 lines |
- #!/bin/ksh
- # @(#) filt.ksh 2.0 96/11/09
- # 92/10/08 john h. dubois iii (john@armory.com)
- # 96/11/09 Added all options.
-
- # Use ksh because sh "type" doesn't exit nonzero if it fails
- # & ksh has continue <n>
-
- name=${0##*/}
- Usage="Usage: $name [-efhcnv] [-f<file>] <filter> [<file> ...]"
- overwrite=false
- backup=true
- check=true
- eval=
- filesGiven=false
- verbose=false
-
- while getopts eohcnf:v opt; do
- case $opt in
- h)
- print -r -- \
- "$name: filter files.
- Each <file> is passed to <filter> as its standard input.
- Output is written to <file>+. If the exit value of <filter> is zero,
- the original file is moved <file>- and the output is moved to <file>.
- $Usage
- Options:
- -h: Print this help.
- -v: Be verbose.
- -e: \"eval\" the filter command. This is neccessary if it contains
- characters that must be interpreted by the shell, like quoting characters.
- Example: $name -e \"grep 'foo bar'\" file
- -f<file>: Specify a file to be filtered. If a filename is given with -f, the
- remaining (non-option) arguments are all taken to be part of the filter
- command. This is an alternative to the -e option for specifying complex
- filter commands. Multiple -f arguments may be given.
- -o: Normally $name will skip a file if <file>+ or (if -n is not given) <file>-
- already exists. If -f is given, they will be overwritten.
- -c: After a successful filter, instead of moving files, copy them: <file>
- is copied to <file>-, <file> is overwritten with the contents of <file>+,
- and then <file>+ is removed. This preserves the original inode of <file>.
- -n: Do not keep a backup copy of <file> in <file>-."
- exit 0
- ;;
- f)
- set -A files -- "${files[@]}" "$OPTARG"
- filesGiven=true
- ;;
- e)
- eval=eval
- ;;
- c)
- overwrite=true
- ;;
- o)
- check=false
- ;;
- n)
- backup=false
- ;;
- v)
- verbose=true
- ;;
- ?)
- print -r -u2 "Use -h for help."
- exit 1
- ;;
- esac
- done
-
- # remove args that were options
- let OPTIND=OPTIND-1
- shift $OPTIND
-
- if [ $# -lt 2 ]; then
- print -r -u2 -- "$Usage
- Use -h for help."
- exit 1
- fi
-
- if $filesGiven; then
- set -A filter -- "$@"
- else
- tm=$1
- shift
- set -A files -- "$@" # some ksh lose positional param when -A used
- set -A filter -- $tm
- fi
-
- type "${filter[0]}" >/dev/null 2>&1 || {
- print -ru2 -- "Cannot execute filter command: ${filter[0]}"
- exit 1
- }
-
- for file in "${files[@]}"; do
- if $check; then
- if [ -f "$filt+" ]; then
- print -ru2 -- "$filt+ already exists. $file not processed."
- continue
- fi
- if $backup && [ -f "$file-" ]; then
- print -ru2 -- "$file- already exists. $file not processed."
- continue
- fi
- fi
- if [ ! -r "$file" ]; then
- print -ru2 -- "$file: cannot read."
- continue
- fi
- $verbose && print -r -- "Filtering $file..."
- if $eval "${filter[@]}" < "$file" > "$file+"; then
- if $backup; then
- $verbose && print -r -- "Backing up $file..."
- $overwrite && cp -- "$file" "$file-" || mv -- "$file" "$file-"
- if [ $? -ne 0 ]; then
- print -ru2 -- \
- "Backup of $file to $file- failed; filtered contents left in $file+"
- exit 1
- fi
- fi
- if $verbose; then
- print -r -- "Old file:"
- l -- "$file"
- print -r -- "After filtering:"
- l -- "$file+"
- print -r -- "Replacing contents of $file with filtered contents..."
- fi
- $overwrite && cat -- "$file+" > "$file" || mv -- "$file+" "$file"
- if [ $? -ne 0 ]; then
- print -ru2 -- \
- "Move of filtered contents to $file back to $file failed;
- contents of $file may be inconsistent!!"
- exit 1
- fi
- if $overwrite; then
- $verbose && print -r -- "Removing $file+..."
- rm -- "$file+"
- fi
- print -r -- "$file succesfully filtered."
- else
- print -r -- "filter exited nonzero on file $file; $file not touched."
- fi
- done
-